#ifndef TEXTURE_H
#define TEXTURE_H
#include <d3dx9.h>
#include <fstream>
#include "singleton.h"
#include "common.h"

struct Vertex_RHW_TEX
{
    float x,y,z,rhw;
    float u,v;
    static DWORD FVF;
};

struct Vertex_RHW_TEX2
{
    float x,y,z,rhw;
    float u1,v1;
    float u2,v2;
    static DWORD FVF;
};

struct Vertex_RHW_CLR
{
    float x,y,z,rhw;
    DWORD color;
    static DWORD FVF;
};

struct Vertex_RHW_CLR_TEX
{
    float x,y,z,rhw;
    DWORD color;
    float u,v;
    static DWORD FVF;
};

#define PATH_MAX 128
struct TextureInfo
{
    IDirect3DTexture9 *texture;
    TCHAR filename[PATH_MAX];
    DWORD width;
    DWORD height;
};

typedef std::vector<TextureInfo> TextureVec;
struct DXUTFontNode;

class CD3DManager:public CSingleton<CD3DManager>
{
    IMPLEMENT_SINGLETON(CD3DManager);
public:
    void Initialize(HWND hwnd);
    int AddTexture( LPCTSTR filename , int colorkey = 0 );
    TextureInfo *GetTextureInfo( int texid );
    IDirect3DTexture9 *LoadTextureFromFile( LPCTSTR filename , int format=D3DFMT_A8R8G8B8, int colorkey = 0 );
	void Clear();
	void BeginRenderMap();
	void EndRenderMap();
	void BeginRenderText();
	void EndRenderText();
    void BeginRender();
    void DrawTexture(int tex, int x, int y, int sizex, int sizey, float u1 = 0.0f, float v1 = 0.0f, float u2 = 1.0f, float v2 = 1.0f);
    void DrawRect( RECT &rect, DWORD color = 0xffff0000, bool fill = false );
    void DrawText( LPCTSTR str, LPRECT rect, D3DCOLOR color = 0xff000000 );
    void EndRender();  
    LPDIRECT3DDEVICE9 GetDevice()
    {
        return m_pDevice;
    }
    IDirect3D9 *GetD3D()
    {
        return m_pD3D;
    }
    HWND    GetHwnd( )
    {
        return m_hwnd;
    }
    void CleanUp();
private:
    HWND m_hwnd;
    IDirect3DDevice9 *m_pDevice;
    IDirect3D9 *m_pD3D;
    TextureVec m_textures;
    ID3DXFont *m_pFont;
    ID3DXSprite *m_pSprite;
};

class CTexture
{
public:
    CTexture();
    ~CTexture();
    bool LoadTexture( LPCTSTR filename , int format=D3DFMT_A8R8G8B8);
    bool LoadTexture( int width, int height,const char *srcdata , int format=D3DFMT_A8R8G8B8 );
    bool LoadTexture( int srcwidth, int srcheight,RECT &rect,const char *srcdata , int format=D3DFMT_A8R8G8B8 );
    void Render( int x, int y, int sizex, int sizey, int color, float u1 = 0.0f, float v1 = 0.0f, float u2 = 1.0f, float v2 = 1.0f );
    void Cleanup();
    void SaveData(std::ofstream &f);
    bool SaveTextureToFile( const TCHAR *filename, int format = D3DXIFF_TGA );
    void ComputeScanline(int startx, int starty, int id);
    void SetColor( int color );
    SIZE &GetSize();

private:
    IDirect3DTexture9 *m_pTexture;
    SIZE m_size;
};

#endif